﻿using System;
using System.Xml;
using InfoJetSoft.Service.Entity;
using InfoJetSoft.Service.Util;

namespace InfoJetSoft.Service.Worker
{
	
	class XSNViewFormatSpanWorker
	{
		//格式化视图中的span. InfoPath视图中的RichText和TextField等文本框都是作为span定义的.
		public static void  formatSpan(View view)
		{
            //CID 1369 //2012.10.07 //Begin
            string xdXctName = NamespaceUtil.toFullName(view.XdPrefix, JetConstant.XD_xctname);
            string xdDisableEditing = NamespaceUtil.toFullName(view.XdPrefix, "disableEditing");
            string contentEditableFilter = NamespaceUtil.toFullName(view.XslPrefix, "choose") +
                 "/" + NamespaceUtil.toFullName(view.XslPrefix, "when") +
                 "/" + NamespaceUtil.toFullName(view.XslPrefix, "attribute") +
                 "[@name='contentEditable']";
            //CID 1369 //2012.10.07 //End

			XmlElement root = view.Doc.DocumentElement;
			string spanFilter = "//span";
			XmlNodeList spanElementList = DOMUtil.selectNodes(root, spanFilter, 0, view.NsResolver);
			for (int i = 0; i < spanElementList.Count; i ++ )
			{
				XmlElement spanElement = (XmlElement) spanElementList[ i ];
				//找出xctName属性,xctName属性定义了控件类型.
                string xctName = spanElement.GetAttribute(xdXctName);
				if( xctName.Length <= 0 ){
					continue;
				}

				//CID 0255 //2009.05.20 //Begin
				spanElement.RemoveAttribute( "hideFocus" );
				//CID 0255 //2009.05.20 //End

				//CID 0129 //2008.10.02 //Begin
				InlineFont( spanElement );
				//CID 0129 //2008.10.02 //End

				//CID 0080 //2008.08.04 //Begin
				if( formatPasswordField( view, spanElement ) )
				{
					continue;
				}
				else
				{
				//CID 0080 //2008.08.04 //End
					//RichText转换为textarea.
					//CID 0080 //2008.08.04 //|| xctName.Equals(JetConstant.XCT_PlainText) added.
					//CID 0255 //2009.05.18 //|| xctName.Equals(JetConstant.XCT_PlainText) removed.
					if (xctName.Equals(JetConstant.XCT_RichText)) 
					{
						//CID 0372 //2009.07.31 //Begin
						if( ConfigUtil.EnableRichText() )
						{
							//CID 1101 //2012.05.25 //Begin
                            //spanElement.SetAttribute("contentEditable", "true");
                            spanElement.SetAttribute("onfocus", "InfoJet_OnRichTextBoxFocus(event, this);");
                            //CID 1101 //2012.05.25 //End
                            //CID 1369 //2012.10.07 //Begin
                            //CID 1208 //2012.05.27 //Begin
                            //spanElement.RemoveAttribute("contentEditable");
                            //CID 1208 //2012.05.27 //End
                            string disableEditing = spanElement.GetAttribute(xdDisableEditing);
                            if (disableEditing != null && disableEditing.Equals("yes"))
                            {
                                //do nothing.
                            }
                            else
                            {
                                spanElement.SetAttribute("contentEditable", "true");
                                //<xsl:choose>
                                //    <xsl:when test="my:域3 = string(true())">
                                //            <xsl:attribute name="contentEditable">false</xsl:attribute>
                                //    </xsl:when>
                                //</xsl:choose>
                                XmlNodeList contentEditableAttrElementList = DOMUtil.selectNodes(spanElement, contentEditableFilter, 0, view.NsResolver);
                                foreach (XmlElement contentEditableAttrElement in contentEditableAttrElementList)
                                {
                                    if (contentEditableAttrElement.InnerText.Equals("false"))
                                    {
                                        XmlElement whenElement = contentEditableAttrElement.ParentNode as XmlElement;
                                        XmlElement chooseElement = whenElement.ParentNode as XmlElement;
                                        XmlElement notWhenElement = view.Doc.CreateElement(view.XslPrefix, "when", JetConstant.URI_XSL);
                                        chooseElement.AppendChild(notWhenElement);
                                        XmlElement trueAttrElement = view.Doc.CreateElement(view.XslPrefix, "attribute", JetConstant.URI_XSL);
                                        notWhenElement.AppendChild(trueAttrElement);
                                        trueAttrElement.InnerText = "true";
                                        trueAttrElement.SetAttribute("name", "contentEditable");
                                        notWhenElement.SetAttribute("test", "not(" + whenElement.GetAttribute("test") + ")");
                                    }
                                }

                            }
                            //CID 1369 //2012.10.07 //End
						}
						else
						{
							spanElement = DOMUtil.renameElementName( spanElement , JetConstant.HTML_textarea );
						}
						//CID 0372 //2009.07.31 //End
						continue;
					}

					//CID 0236 //2009.03.03 //Begin
					if( xctName.Equals(JetConstant.XCT_multiselectlistbox) )
					{
						formatMultiSelectListBox( view, spanElement );
					}
					//CID 0236 //2009.03.03 //End

                    //CID 0459 //2011.04.13 //Begin
                    if (xctName.Equals(JetConstant.XCT_FileAttachment))
                    {
                        spanElement.RemoveAttribute("tabIndex");
                        continue;
                    }
                    //CID 0459 //2011.04.13 //End

					//下列类型不需要处理.
					if (xctName.Equals(JetConstant.XCT_multiselectlistbox) || 
						xctName.Equals(JetConstant.XCT_combobox) || 
						xctName.Equals(JetConstant.XCT_RepeatingSection) || 
						xctName.Equals(JetConstant.XCT_BulletedList) || 
						xctName.Equals(JetConstant.XCT_NumberedList) || 
						xctName.Equals(JetConstant.XCT_PlainList) || 
						xctName.Equals(JetConstant.XCT_ExpressionBox) || 
						//CID 0424 //2009.10.16 //Begin
						xctName.Equals(JetConstant.XCT_LayoutRegion) || 
						//CID 0424 //2009.10.16 //End
                        //CID 0638 //2010.08.07 //Begin
                        xctName.Equals(JetConstant.XCT_HyperlinkBox) ||
                        //CID 0638 //2010.08.07 //End
						//CID 0228 //2009.02.17 //Begin
						xctName.ToLower().Equals(JetConstant.XCT_hyperlink) )  //hyperlink也不需要将span转换为input,见Forms2007\Hyperlink\Hyperlinks.xsn和HyperlinkTest2.xsn.
						//CID 0228 //2009.02.17 //End
					{
						continue;
					}

					//其它的span都转化为input text.
					spanElement = DOMUtil.renameElementName( spanElement , "input" );
                    spanElement.SetAttribute("type", "text");
                    //CID 0884 //2011.04.23 //Begin
                    spanElement.SetAttribute("autocomplete", "off");
                    //CID 0884 //2011.04.23 //End
				}
			}
		}

		//CID 0236 //2009.03.03 //Begin
		private static void formatMultiSelectListBox( View view, XmlElement spanElement )
		{
			string xdRef = spanElement.GetAttribute( NamespaceUtil.toFullName( view.XdPrefix, "ref" ) );
			string xdCtrlId = spanElement.GetAttribute( NamespaceUtil.toFullName( view.XdPrefix, "CtrlId" ) );
			if( xdRef.Length > 0 && xdCtrlId.Length > 0 )
			{
                //CID 1136 //2012.03.16 //Begin
                //CID 0661 //2010.09.15 //Begin
                string refPath = formatRefPath(xdRef);
                //CID 0661 //2010.09.15 //End
                //CID 1136 //2012.03.16 //End
				bool found = false;
				foreach( XmlToEdit xmlToEdit in view.Manifest.XmlToEditList )
				{
                    //CID 0661 //2010.09.15 //EndsWith(refPath)
					if( (xmlToEdit.ViewContext.Length == 0 || xmlToEdit.ViewContext.Equals( xdCtrlId ) )
                        && xmlToEdit.Item.EndsWith(refPath) && xmlToEdit.ViewName.Equals(view.Name))
					{
						xmlToEdit.MultiSelectListBoxRef = xdRef;
						spanElement.SetAttribute( "xmlToEdit", xmlToEdit.Name );
						found = true;
						break;
					}
				}
				if( !found )
				{
					throw new InfoJetSoft.Service.InfoJetException( "Cannot find the MultipleSelectListBox's XmlToEdit.", "XVFW01" );
				}
				//CID 0546 //2010.05.11 //Begin
				spanElement.SetAttribute( "contextId", "{./@" + JetConstant.JetId + "}" );
				//CID 0546 //2010.05.11 //End
			}
		}
		//CID 0236 //2009.03.03 //End

        //CID 1136 //2012.03.16 //Begin
        private static string formatRefPath(string refPath)
        {
            System.Text.StringBuilder buffer = new System.Text.StringBuilder();
            char[] chars = refPath.ToCharArray();
            bool isIgnored = true;
            foreach(char chr in chars)
            {
                if (chr == '.' || chr == '/')
                {
                    if (!isIgnored)
                    {
                        buffer.Append(chr);
                    }
                }
                else
                {
                    isIgnored = false;
                    buffer.Append(chr);
                }
            }
            buffer.Insert(0, '/');
            return buffer.ToString();
        }
        //CID 1136 //2012.03.16 //End

		//CID 0129 //2008.10.02 //Begin
		//将<span>外部的<font>标签转到内部.
		private static void InlineFont( XmlElement spanElement )
		{
			XmlElement parentElement = spanElement.ParentNode as XmlElement;
			if( parentElement.Name.ToLower().Equals( "font" ) )
			{
				string fontStyle = "";
				//CID 0460 //2009.11.12 //Begin
				XmlElement outerElement = parentElement.ParentNode as XmlElement;
				if( outerElement.Name.ToLower().Equals( "strong" ) )
				{
					fontStyle = fontStyle + ";FONT-WEIGHT:BOLD";
				}
				//CID 0460 //2009.11.12 //End
				string fontSize = parentElement.GetAttribute( "size" );
				if( fontSize != null && fontSize.Length > 0 )
				{
					if( fontSize.Equals( "1" ) )
					{
						fontStyle = fontStyle + ";FONT-SIZE:xx-small";
					}
					else if( fontSize.Equals( "2" ) )
					{
						fontStyle = fontStyle + ";FONT-SIZE:x-small";
					}
					else if( fontSize.Equals( "3" ) )
					{
						fontStyle = fontStyle + ";FONT-SIZE:small";
					}
					else if( fontSize.Equals( "4" ) )
					{
						fontStyle = fontStyle + ";FONT-SIZE:medium";
					}
					else if( fontSize.Equals( "5" ) )
					{
						fontStyle = fontStyle + ";FONT-SIZE:large";
					}
					else if( fontSize.Equals( "6" ) )
					{
						fontStyle = fontStyle + ";FONT-SIZE:x-large";
					}
					else if( fontSize.Equals( "7" ) )
					{
						fontStyle = fontStyle + ";FONT-SIZE:xx-large";
					}
				}
				string fontFace = parentElement.GetAttribute( "face" );
				if( fontFace != null && fontFace.Length > 0 )
				{
					fontStyle = fontStyle + ";FONT-FAMILY:" + fontFace;
				}
				if( fontStyle.Length > 0 )
				{
					fontStyle = fontStyle + ";";
					string spanStyle = spanElement.GetAttribute( "style" );
					if( spanStyle != null && spanStyle.Length > 0 )
					{
						//CID 0460 //2009.11.12 //Begin
						spanStyle = fontStyle + spanStyle;
						//CID 0460 //2009.11.12 //End
					}
					else
					{
						spanStyle = fontStyle;
					}
					spanElement.SetAttribute( "style", spanStyle );
				}
			}
		}
		//CID 0129 //2008.10.02 //Begin

		//根据InfoJetService.config中的PasswordField声明,将input text格式化成input password.
		private static bool formatPasswordField( View view, XmlElement spanElement )	//CID 0080 //2008.08.04 //bool
		{
			string xdBinding = NamespaceUtil.toFullName(view.XdPrefix, JetConstant.XD_binding);
			string binding = spanElement.GetAttribute( xdBinding );
			if( binding != null && binding.Length > 0 )
			{
				if( view.Manifest.FormConfiguration.IsPasswordField( binding ) )
				{
					spanElement = DOMUtil.renameElementName( spanElement , "input" );
					spanElement.SetAttribute("type", "password");
					return true;
				}
			}
			return false;
		}

	}
}